/*
 * The contents of this file are subject to the Mozilla Public License
 * Version 1.1 (the "License");  you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * http//www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
 * the specific language governing rights and limitations under the License.
 *
 * The Original Code is ART OWL API.
 *
 * The Initial Developer of the Original Code is University of Roma Tor Vergata.
 * Portions created by University of Roma Tor Vergata are Copyright (C) 2009.
 * All Rights Reserved.
 *
 * The ART OWL API were developed by the Artificial Intelligence Research Group
 * (art.uniroma2.it) at the University of Roma Tor Vergata
 * Current information about the ART OWL API can be obtained at 
 * http://art.uniroma2.it/owlart
 *
 */

package it.uniroma2.art.owlart.models;

import it.uniroma2.art.owlart.exceptions.ModelCreationException;
import it.uniroma2.art.owlart.exceptions.ModelUpdateException;
import it.uniroma2.art.owlart.exceptions.VocabularyInitializationException;
import it.uniroma2.art.owlart.vocabulary.OWL;
import it.uniroma2.art.owlart.vocabulary.RDF;
import it.uniroma2.art.owlart.vocabulary.RDFS;

import java.util.HashSet;
import java.util.Set;

/**
 * a standard implementation of {@link ModelFactory} which takes the duty of loading basic vocabularies of the
 * RDF family (RDF, RDFS, OWL) according to the specific type of model which is being loaded
 * 
 * @author Armando Stellato
 * 
 */
public class OWLArtModelFactory implements ModelFactory {

	private ModelFactory modelFactoryImpl;

	private Set<Object> initializationSet;

	/**
	 * basic constructor which encapsulates a {@link ModelFactory} plain implementation and adds vocabulary
	 * management to it
	 * 
	 * @param mf
	 */
	private OWLArtModelFactory(ModelFactory mf) {
		this.modelFactoryImpl = mf;
		initializationSet = new HashSet<Object>();
	}

	/**
	 * basic factory which creates an instance of this class by encapsulating a {@link ModelFactory} plain
	 * implementation and adding vocabulary management to it
	 * 
	 * @param mf
	 * @return
	 */
	public static OWLArtModelFactory createModelFactory(ModelFactory mf) {
		return new OWLArtModelFactory(mf);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * it.uniroma2.art.owlart.models.ModelFactory#closeModel(it.uniroma2.art.owlart.models.BaseRDFTripleModel)
	 */
	public void closeModel(BaseRDFTripleModel rep) throws ModelUpdateException {
		modelFactoryImpl.closeModel(rep);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see it.uniroma2.art.owlart.models.ModelFactory#loadRDFBaseModel(java.lang.String, java.lang.String,
	 * boolean)
	 */
	public BaseRDFTripleModel loadRDFBaseModel(String baseuri, String repositoryDirectory, boolean persist)
			throws ModelCreationException {
		BaseRDFTripleModel md = modelFactoryImpl.loadRDFBaseModel(baseuri, repositoryDirectory, persist);
		try {
			post_initialize(md, baseuri, repositoryDirectory);
		} catch (ModelUpdateException e) {
			throw new ModelCreationException(e);
		}
		return md;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see it.uniroma2.art.owlart.models.ModelFactory#loadRDFModel(java.lang.String, java.lang.String,
	 * boolean)
	 */
	public RDFModel loadRDFModel(String baseuri, String repositoryDirectory, boolean persist)
			throws ModelCreationException {
		RDFModel md = modelFactoryImpl.loadRDFModel(baseuri, repositoryDirectory, persist);
		try {
			if (!initializationSet.contains(RDF.Res.class))
				RDF.Res.initialize(md);
			if (!initializationSet.contains(RDFS.Res.class))
				RDFS.Res.initialize(md);
			post_initialize(md, baseuri, repositoryDirectory);

		} catch (VocabularyInitializationException e) {
			throw new ModelCreationException(e);
		} catch (ModelUpdateException e) {
			throw new ModelCreationException(e);
		}

		return md;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see it.uniroma2.art.owlart.models.ModelFactory#loadRDFSModel(java.lang.String, java.lang.String,
	 * boolean)
	 */
	public RDFSModel loadRDFSModel(String baseuri, String repositoryDirectory, boolean persist)
			throws ModelCreationException {
		RDFSModel md = modelFactoryImpl.loadRDFSModel(baseuri, repositoryDirectory, persist);
		try {

			if (!initializationSet.contains(RDF.Res.class))
				RDF.Res.initialize(md);
			if (!initializationSet.contains(RDFS.Res.class))
				RDFS.Res.initialize(md);
			post_initialize(md, baseuri, repositoryDirectory);

		} catch (VocabularyInitializationException e) {
			throw new ModelCreationException(e.getCause());
		} catch (ModelUpdateException e) {
			throw new ModelCreationException(e);
		}

		return md;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see it.uniroma2.art.owlart.models.ModelFactory#loadOWLModel(java.lang.String, java.lang.String,
	 * boolean)
	 */
	public OWLModel loadOWLModel(String baseuri, String repositoryDirectory, boolean persist)
			throws ModelCreationException {
		OWLModel md = modelFactoryImpl.loadOWLModel(baseuri, repositoryDirectory, persist);
		try {
			if (!initializationSet.contains(RDF.Res.class))
				RDF.Res.initialize(md);
			if (!initializationSet.contains(RDFS.Res.class))
				RDFS.Res.initialize(md);
			if (!initializationSet.contains(OWL.Res.class))
				OWL.Res.initialize(md);
			post_initialize(md, baseuri, repositoryDirectory);

		} catch (VocabularyInitializationException e) {
			throw new ModelCreationException(e);
		} catch (ModelUpdateException e) {
			throw new ModelCreationException(e);
		}

		return md;
	}

	/**
	 * this method takes care of specific post-initialization issues after a model has been loaded.<br/>
	 * It is invoked by the various loadMethods available in this class<br/>
	 * Currently, it just sets the baseURI for the loaded ontology.
	 * 
	 * @param rep
	 * @param baseuri
	 * @param repositoryDirectory
	 * @throws ModelUpdateException
	 */
	private void post_initialize(BaseRDFTripleModel rep, String baseuri, String repositoryDirectory)
			throws ModelUpdateException {
		rep.setBaseURI(baseuri);
	}

}
